package com.ohos.connect.devicecloud.app.modular.project.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ohos.connect.devicecloud.app.modular.project.model.vo.ProjectVO;
import com.ohos.connect.devicecloud.app.modular.projectdevice.model.entity.ProjectDevice;
import com.ohos.connect.devicecloud.app.modular.projectdevice.service.ProjectDeviceService;
import com.ohos.connect.devicecloud.app.modular.projectuser.enums.ProjectUserRoleEnum;
import com.ohos.connect.devicecloud.app.modular.projectuser.model.dto.ProjectUserAddDTO;
import com.ohos.connect.devicecloud.app.modular.projectuser.model.dto.ProjectUserSearchDTO;
import com.ohos.connect.devicecloud.app.modular.projectuser.model.entity.ProjectUser;
import com.ohos.connect.devicecloud.app.modular.projectuser.service.ProjectUserService;
import com.ohos.connect.devicecloud.auth.core.util.StpAppLoginUserUtil;
import com.ohos.connect.devicecloud.mqtt.api.MqttApi;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ohos.connect.devicecloud.common.exception.CommonException;
import com.ohos.connect.devicecloud.app.modular.project.model.entity.Project;
import com.ohos.connect.devicecloud.app.modular.project.mapper.ProjectMapper;
import com.ohos.connect.devicecloud.app.modular.project.model.dto.ProjectAddDTO;
import com.ohos.connect.devicecloud.app.modular.project.model.dto.ProjectEditDTO;
import com.ohos.connect.devicecloud.app.modular.project.model.dto.ProjectIdDTO;
import com.ohos.connect.devicecloud.app.modular.project.service.ProjectService;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @Description:  APP项目Service接口实现类
 * @Author: Dongtao
 * @Date:  2024/12/05 10:46
 **/
@Service
public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> implements ProjectService {

    @Resource
    private ProjectUserService projectUserService;

    @Resource
    private ProjectDeviceService projectDeviceService;

    @Resource
    private MqttApi mqttApi;

    @Override
    public List<ProjectVO> getProjectListByAppUser() {
        List<ProjectVO> resultList = new ArrayList<>();
        // 1.获取用户id
        String userId = StpAppLoginUserUtil.getAppLoginUserId();

        // 根据用户ID查询项目Id
        QueryWrapper<ProjectUser> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.lambda()
                .eq(ProjectUser::getAppUserId,userId)
                .orderByDesc(ProjectUser::getCreateTime);
        List<ProjectUser> projectUserList = projectUserService.list(queryWrapper1);

        for (ProjectUser projectUser : projectUserList) {
            Project project = this.getById(projectUser.getProjectId());
            if(ObjectUtil.isNotEmpty(project)){
                ProjectVO projectVO = new ProjectVO();
                BeanUtil.copyProperties(project, projectVO);
                projectVO.setRole(projectUser.getRole());
                projectVO.setConfirmStatus(projectUser.getConfirmStatus());
                resultList.add(projectVO);
            }
        }

        return resultList;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean add(ProjectAddDTO projectAddDTO) {
        // 1.获取用户id
        String userId = StpAppLoginUserUtil.getAppLoginUserId();
        // 2.校验项目名
        checkProjectName(projectAddDTO,userId);
        // 3.插入项目app_project表
        Project project = BeanUtil.toBean(projectAddDTO, Project.class);
        Boolean insertProject = this.save(project);
        // 4.插入app_project_user表
        ProjectUserAddDTO projectUserAddDTO = new ProjectUserAddDTO();
        projectUserAddDTO.setProjectId(project.getId());
        projectUserAddDTO.setAppUserId(userId);
        projectUserAddDTO.setRole(ProjectUserRoleEnum.OWNER);
        Boolean insertProjectUser = projectUserService.add(projectUserAddDTO);
        return insertProject&insertProjectUser;
    }

    private void checkProjectName(ProjectAddDTO projectAddDTO, String userId){
        if(ObjectUtil.isEmpty(projectAddDTO.getName())) {
            throw new CommonException("项目名称不能为空!");
        }
        // 获取该用户的projectIdList
        ProjectUserSearchDTO projectUserSearchDTO = new ProjectUserSearchDTO();
        projectUserSearchDTO.setAppUserId(userId);
        List<ProjectUser> projectUserList = projectUserService.getProjectsByAppUserId(projectUserSearchDTO);
        // 校验新的项目名是否重复
        if(ObjectUtil.isNotEmpty(projectUserList)) {
            for(ProjectUser projectUser : projectUserList) {
                Project project = this.getById(projectUser.getProjectId());
                if( ObjectUtil.isNotEmpty(project) && projectAddDTO.getName().equals(project.getName())){
                    throw new CommonException("当前用户下已有该项目: " + project.getName());
                }
            }
        }
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean edit(ProjectEditDTO projectEditDTO) {
        projectUserService.getProjectUserByProjectId(projectEditDTO.getId());
        Project project = this.queryEntity(projectEditDTO.getId());

        if(ObjectUtil.isNotEmpty(projectEditDTO.getName())){
            project.setName(projectEditDTO.getName());
        }
        if(ObjectUtil.isNotEmpty(projectEditDTO.getDescription())){
            project.setDescription(projectEditDTO.getDescription());
        }
        if(ObjectUtil.isNotEmpty(projectEditDTO.getLocationName())){
            project.setLocationName(projectEditDTO.getLocationName());
        }
        if(ObjectUtil.isNotEmpty(projectEditDTO.getLongitude())){
            project.setLongitude(projectEditDTO.getLongitude());
        }
        if(ObjectUtil.isNotEmpty(projectEditDTO.getLatitude())){
            project.setLatitude(projectEditDTO.getLatitude());
        }
         Boolean result = this.updateById(project);
        if(!result){
            throw new CommonException("修改项目信息失败");
        }

        // 向APP发送项目信息变化通知
        sendProjectInfoChangedNotice(project.getId(),project.getName());

        return result;
    }

    // 向APP发送项目信息变化通知
    private void sendProjectInfoChangedNotice(String projectId,String projectName){
        // 根据项目id获取用户account
        ProjectUser  projectUser = projectUserService.getProjectUserByProjectId(projectId);

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<ProjectIdDTO> projectIdDTOList) {
        // 执行删除
        if(ObjectUtil.isEmpty(projectIdDTOList)){
            throw new CommonException("项目id不能为空");
        }
        for(ProjectIdDTO projectIdDTO : projectIdDTOList){
            projectUserService.getProjectUserByProjectId(projectIdDTO.getId());
        }
        this.removeByIds(CollStreamUtil.toList(projectIdDTOList, ProjectIdDTO::getId));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean deleteById(String id) {
        if(ObjectUtil.isNull(id)){
            throw new CommonException("项目id不能为空");
        }
        // 校验projectId是否属于当前登录帐号
        ProjectUser projectUser = projectUserService.getProjectUserByProjectId(id);

        // 校验当前用户对于该项目是否是Owner角色
        if( !ProjectUserRoleEnum.OWNER.equals(projectUser.getRole()) ){
            throw new CommonException("当前用户不是该项目的所有者，无法删除");
        }

        // 获取用户id
        String userId = StpAppLoginUserUtil.getAppLoginUserId();

        // 获取当前APP帐号底下的项目数量
        QueryWrapper<ProjectUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(ProjectUser::getAppUserId,userId);
        List<ProjectUser> projectUserList = projectUserService.list(queryWrapper);
        if(1 == projectUserList.size()){
            throw new CommonException("最后一个项目无法删除");
        }

        // 删除projectUser  projectDevice记录
        QueryWrapper<ProjectUser> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.lambda().eq(ProjectUser::getProjectId,id);
        boolean deleteProjectUsers = projectUserService.remove(queryWrapper1);
        if(!deleteProjectUsers){
            throw new CommonException("删除项目用户记录失败");
        }

        QueryWrapper<ProjectDevice> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.lambda().eq(ProjectDevice::getProjectId,id);
        List<ProjectDevice> projectDeviceList = projectDeviceService.list(queryWrapper2);
        // 有项目设备记录，才清除
        if(ObjectUtil.isNotEmpty(projectDeviceList) ){
            boolean deleteProjectDevices = projectDeviceService.remove(queryWrapper2);
            if(!deleteProjectDevices){
                throw new CommonException("删除项目设备记录失败");
            }
        }

        // 执行删除
        boolean deleteProject = this.removeById(id);
        if(!deleteProject){
            throw new CommonException("删除项目失败");
        }

        return true;
    }

    @Override
    public Project detail(ProjectIdDTO projectIdDTO) {
        projectUserService.getProjectUserByProjectId(projectIdDTO.getId());
        return this.queryEntity(projectIdDTO.getId());
    }

    @Override
    public Project queryEntity(String id) {
        Project project = this.getById(id);
        if(ObjectUtil.isEmpty(project)) {
            throw new CommonException("APP项目不存在，id值为：{}", id);
        }
        return project;
    }
}
